/****************************************
 * Copyright (c) 2015 NiuWa.
 * All rights reserved.
 * Created on 2015年3月19日
 * 
 * Contributors:
 * 	bwz - initial implementation
 ****************************************/
package com.niuwa.p2p.service.impl.business;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.niuwa.p2p.core.utils.DateUtil;
import com.niuwa.p2p.core.utils.DictConstant;
import com.niuwa.p2p.core.utils.StringUtil;
import com.niuwa.p2p.dao.business.IDirectProductDao;
import com.niuwa.p2p.dao.business.LoanClaimDao;
import com.niuwa.p2p.dao.business.ProdAuditDao;
import com.niuwa.p2p.dao.business.ProdRelativeProtDao;
import com.niuwa.p2p.dao.customer.CustomerDao;
import com.niuwa.p2p.dao.productTemplate.ProductDao;
import com.niuwa.p2p.dao.productTemplate.ProductTemplateDao;
import com.niuwa.p2p.dao.protocol.ProtocolDao;
import com.niuwa.p2p.dao.user.UserDao;
import com.niuwa.p2p.entity.business.DirectProduct;
import com.niuwa.p2p.entity.business.ProdAudit;
import com.niuwa.p2p.entity.business.ProdRelativeProt;
import com.niuwa.p2p.entity.customer.Customer;
import com.niuwa.p2p.entity.productTemplate.Product;
import com.niuwa.p2p.entity.productTemplate.ProductTemplate;
import com.niuwa.p2p.entity.user.User;
import com.niuwa.p2p.service.business.IDirectProductService;
import com.niuwa.p2p.utils.DateFormatUtils;
import com.niuwa.p2p.vo.business.ClaimDetailVo;
import com.niuwa.p2p.vo.business.LoanClaimOriginVo;
import com.niuwa.p2p.vo.business.ProductVo;
import com.niuwa.p2p.vo.front.product.FrontProductDetailVo;
import com.niuwa.p2p.vo.front.product.FrontProductListVo;

/**
 * @title 直投产品Service实现类
 *
 * @author bwz
 * @version 1.0
 * @created 2015年3月19日
 */
@Service
public class DirectProductServiceImpl implements IDirectProductService {

	@Autowired
	private IDirectProductDao directProductDao;

	@Autowired
	private ProductDao productDao;

	@Autowired
	private ProdAuditDao prodAuditDao;

	@Autowired
	private LoanClaimDao loanClaimDao;

	@Autowired
	private ProdRelativeProtDao prodRelativeProtDao;

	@Autowired
	private ProtocolDao protocolDao;

	@Autowired
	private ProductTemplateDao productTemplDao;

	@Autowired
	private UserDao userDao;
	
	@Autowired
	private CustomerDao customerDao;
	
	
	
	@Override
	public int addDirectProduct(DirectProduct product) {
		return directProductDao.addDirectProduct(product);
	}

	@Override
	public int getCountByProjectNo(String projectNo) {
		return directProductDao.getCountByProjectNo(projectNo);
	}

	@Override
	public DirectProduct selectDirectProdByCode(String prodCode)
			throws Exception {

		return directProductDao.selectDirectProdByCode(prodCode);
	}

	@Override
	public void updateDirectProduct(DirectProduct product) throws Exception {
		directProductDao.updateDirectProduct(product);
	}

	
	/**
	 * 申请发布
	 */
	@Override
	public Map<String,Object> applyPublish(ProductVo productVo, String operateType) throws Exception {
		
		String resultMsg = "";
		Map<String,Object> resultMap = new HashMap<String,Object>();
		
		
		
		DirectProduct directPrd = directProductDao.selectDirectProdByCode(productVo.getProductCode());
		
		LoanClaimOriginVo loanClaim = loanClaimDao.selectClaimLoanDetailByProjectNo(directPrd.getProjectNo());
		
		//判断起售金额、递增金额、购买上限，3个金额不能大于债权或借款的总金额
		if(loanClaim.getProjectType().equals(DictConstant.ProjectType.LOAN.getCode())){
			int maxCompareResult = productVo.getMaxAmount().compareTo(loanClaim.getLoanAmount());
			int minCompareResult = productVo.getMinAmount().compareTo(productVo.getMaxAmount());
			int stepCompareResult = productVo.getStepAmount().compareTo(productVo.getMaxAmount());
			
			if(maxCompareResult > 0){
				resultMsg = "购买上限不能大于借款金额";
				resultMap.put("flag", false);
				resultMap.put("resultMsg", resultMsg);
				return resultMap;
			}
			if(minCompareResult > 0){
				resultMsg = "起售金额不能大于购买上限";
				resultMap.put("flag", false);
				resultMap.put("resultMsg", resultMsg);
				return resultMap;
			}
			if(stepCompareResult > 0){
				resultMsg = "递增金额不能大于购买上限";
				resultMap.put("flag", false);
				resultMap.put("resultMsg", resultMsg);
				return resultMap;
			}
		}
		
		if(loanClaim.getProjectType().equals(DictConstant.ProjectType.CLAIM.getCode())){
			int maxCompareResult = productVo.getMaxAmount().compareTo(loanClaim.getRemainClaimAmount());
			int minCompareResult = productVo.getMinAmount().compareTo(productVo.getMaxAmount());
			int stepCompareResult = productVo.getStepAmount().compareTo(productVo.getMaxAmount());
			
			if(maxCompareResult > 0){
				resultMsg = "购买上限不能大于债权余额";
				resultMap.put("flag", false);
				resultMap.put("resultMsg", resultMsg);
				return resultMap;
			}
			if(minCompareResult > 0){
				resultMsg = "起售金额不能大于购买上限";
				resultMap.put("flag", false);
				resultMap.put("resultMsg", resultMsg);
				return resultMap;
			}
			if(stepCompareResult > 0){
				resultMsg = "递增金额不能大于购买上限";
				resultMap.put("flag", false);
				resultMap.put("resultMsg", resultMsg);
				return resultMap;
			}
		}
		

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String fmtReleaseTime = sdf.format(productVo.getReleaseTime()) + " " + productVo.getReleaseTimeHr() + ":00:00";
		productVo.setReleaseTime(sdf2.parse(fmtReleaseTime));

		String fmtStartSellTime = sdf.format(productVo.getStartSellTime()) + " " + productVo.getStartSellTimeHr() + ":00:00";
		productVo.setStartSellTime(sdf2.parse(fmtStartSellTime));

		// 1、更新p2p_direct_product表
		directPrd.setBidStopTime(productVo.getBidStopTime());
		directPrd.setIsTrans(productVo.getIsTrans());
		//directPrd.setOverdueServiceRate(productVo.getOverdueServiceRate());
		directPrd.setInvestServiceFee(productVo.getInvestServiceFee());//添加投资服务费率
		directPrd.setPrepaymentFee(productVo.getPrepaymentFee());//提前还款补偿金
		if("Y".equals(productVo.getIsTrans())){ //不允许转让时不设置转让费率
			directPrd.setTransRate(productVo.getTransRate());
		}else{
			directPrd.setTransRate(null);
		}
		directPrd.setDirectProdType(productVo.getDirectProdType());
		directProductDao.updateDirectProduct(directPrd);

		// 2、更新p2p_product表
		productVo.setProjectNo(directPrd.getProjectNo());

		Product product = productDao.getProductByProdCode(productVo.getProductCode());
		// 设置初始创建世间
		if(product.getCreateTime() == null){
			productVo.setCreateTime(new Date());
		}
		BeanUtils.copyProperties(productVo, product);

		// 如果有效时间为不限，则不设置停售时间
		if ("N".equals(productVo.getIsValidTerm()) || StringUtil.isEmpty(productVo.getIsValidTerm())) {
			Date endDate = acquireEndSellTime(productVo.getStartSellTime(),
					productVo.getStartSellTimeHr(), productVo.getValidTerm(),
					productVo.getValidTermType());

			product.setEndSellTime(endDate);
		}
		//判断强制流标日的存在
		if(productVo.getForceLoseDate() != null && productVo.getStartSellTime() != null){
			//根据起售时间，设置有效时间
			long vaidDay = DateUtil.getSubDay(productVo.getForceLoseDate() , productVo.getStartSellTime());
			product.setValidTerm((int)vaidDay);
			product.setIsValidTerm("Y");
			product.setValidTermType("D");
			product.setEndSellTime(productVo.getForceLoseDate());
		}
		productDao.updateProduct(product);

		// 3、更新p2p_loan_claim表,编辑时不改变项目状态
		if (operateType.equals(DictConstant.ProdOperateType.APPLY_RELEASE.getCode())) {
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("releaseStatus",DictConstant.ReleaseStatus.WAIT_AUDIT.getCode());
			paramMap.put("projectNo", directPrd.getProjectNo());
			updateStatus(paramMap);
		}

		// 4、写日志`p2p_prod_audit`
		ProdAudit prodAudit = new ProdAudit();
		prodAudit.setProdCode(product.getProductCode());
		prodAudit.setOperateType(operateType);
		prodAudit.setOperator(productVo.getOperator());
		prodAudit.setCreateTime(new Date());

		addProductAuditLog(prodAudit);

		// 产品关联协议
		prodRelativeProtDao.deleteProdRelativeProtByProd(product
				.getProductCode());
		if (null != productVo.getProtId() && productVo.getProtId().length > 0) {
			List<ProdRelativeProt> prp = formatTempProt(
					product.getProductCode(), productVo.getProtId());
			prodRelativeProtDao.saveProdRelativeProt(prp);
		}

		resultMap.put("flag", true);
		resultMap.put("resultMsg", "操作成功");
		return resultMap;
	}

	// 更新状态
	private void updateStatus(Map<String, Object> paramMap) throws Exception {
		loanClaimDao.updateLoanClaimStatus(paramMap);
	}

	// 写产品操作记录信息
	private void addProductAuditLog(ProdAudit prodAudit) throws Exception {
		prodAuditDao.addProdAudit(prodAudit);
	}

	/**
	 * 新增选中的协议信息列表
	 * 
	 * @param tempId
	 * @param form
	 */
	private List<ProdRelativeProt> formatTempProt(String prodCode,
			String[] protId) {
		List<ProdRelativeProt> tpList = new ArrayList<ProdRelativeProt>();
		for (int index = 0; index < protId.length; index++) {
			ProdRelativeProt tp = new ProdRelativeProt();
			tp.setProd(prodCode);
			if (null != protId[index] && !"".equals(protId[index]))
				tp.setProtId(Long.valueOf(protId[index]));
			tpList.add(tp);
		}
		return tpList;
	}

	/**
	 * 根据起售时间、有效时间计算停售时间
	 * 
	 * @param startSellTime
	 * @param startSellTimeHr
	 * @param validTerm
	 * @param validTermType
	 * @return
	 */
	private Date acquireEndSellTime(Date startSellTime, String startSellTimeHr,
			int validTerm, String validTermType) {
		Date date = null;
		try {
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
			SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			if (validTerm > 0 && StringUtils.isNotBlank(validTermType)) {
				int day = 0;
				if (DictConstant.TermType.D.getCode().equals(validTermType)) {
					day = validTerm;
				} else if (DictConstant.TermType.M.getCode().equals(
						validTermType)) {
					day = validTerm * 30; // TODO 待定30
				} else if (DictConstant.TermType.Y.getCode().equals(
						validTermType)) {
					day = validTerm * 365; // TODO 待定365
				}
				date = DateFormatUtils.getAppointedDayAfterDay(startSellTime,
						day);
				String tempTime = sf.format(date) + " " + startSellTimeHr
						+ ":00:00";
				date = new Timestamp(sft.parse(tempTime).getTime());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	@Override
	public ClaimDetailVo getProductRelativeInfo(String productCode)
			throws Exception {

		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("productCode", productCode);
		ClaimDetailVo claimDetailVo = productDao.getClaimDetail(paramMap);
		
		if (claimDetailVo != null) {
			if (claimDetailVo.getTempId() != null) {
				ProductTemplate pTemplate = productTemplDao
						.selectByTempId(claimDetailVo.getTempId());
				if (pTemplate != null) {
					claimDetailVo.setTempName(pTemplate.getTempName());
				}
			}
			// 获取协议信息
			claimDetailVo.setProductProtocols(protocolDao
					.getProdRelativeProt(productCode));
			if(claimDetailVo.getOperator() != null){
				User operUser = userDao.selectByUserId(claimDetailVo.getOperator());
				if(operUser != null){
					claimDetailVo.setOperatorName(operUser.getUserName());
				}
			}
		}
		
		/*if(claimDetailVo.getLender() != null){
			Customer lenderCustomer = customerDao.findCustomerById(String.valueOf(claimDetailVo.getLender()));
			if(lenderCustomer != null){
				claimDetailVo.setLenderName(lenderCustomer.getLoginName());
			}
		}*/

		return claimDetailVo;
	}

	
	
	//====================== 前台使用 begin ==============================
	@Override
	public List<FrontProductListVo> selectChoicenessProductListPage(Map<String, Object> paramMap) throws Exception {
		List<FrontProductListVo> productList = productDao.selectChoicenessProductListPage(paramMap);
		return productList;
	}

	
	@Override
	public FrontProductDetailVo getDirectProductDetail(Map<String, Object> paramMap) {
		FrontProductDetailVo fProdDetailVo = productDao.getDirectProductDetail(paramMap);
		return fProdDetailVo;
	}

	
	
	//====================== 前台使用 end ==============================

}



